/**
 * Collaborative Story Development Web Application (CSDApp) Copyright Anton
 * Strack 2014
 *
 * This file is part of Collaborative Story Development Application (CSDApp).
 *
 * CSDApp is free software: you can redistribute it and/or modify it under the
 * terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or any later version.
 *
 * CSDApp is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * CSDApp. If not, see <http://www.gnu.org/licenses/>.
 *
 */
package csdwa;

import java.sql.Connection;

/**
 * This class provides core functionality for all other resource type
 * controllers.
 *
 * @author Anton Strack
 */
public abstract class ResourceController implements CsdwaController {

    protected ResourceRequestDelegator ResourceRequestDelegator;
    protected final String NUMBER_PATTERN;
    protected Connection conn;
    // protected String requestView = "/index.jsp";
    protected String requestResultMessage;
    protected int initialActionTypeId = 0;
    protected int initialResourceTypeId = 0;

    public ResourceController(Connection conn) {
        this.NUMBER_PATTERN = "[0-9]{1,5}?";
        this.conn = conn;
        this.ResourceRequestDelegator = new ResourceRequestDelegator(conn);
    }

    /**
     * This is the entry method into the controller and it returns the completed
     * request object
     *
     * @param request the request for the particular resource to handle.
     * @return the the completed request.
     */
    @Override
    public final CsdwaRequest handleRequest(CsdwaRequest request) {
        request = this.requestStartHandle(request);
        request = this.requestCoreHandle(request);
        request = this.requestEndHandle(request);
        return request;
    }

    /**
     * This method handles get requests. It accepts the primaryResouce and
     * primaryAction as variables to allow routing from the handleGetRequest
     * method.
     *
     * @param primaryResource the primary resource that will handle the request
     * @param primaryAction the primary action on the resource.
     * @param id the id of the particular resource
     * @param request the request object
     *
     * @return an updated request object sufficient to complete the request.
     */
    public abstract CsdwaRequest handleGetRequest(CsdwaRequest request);

    /**
     * This method primarily handles form related requests.
     *
     * @param primaryResource the primary resource that will handle the request
     * @param primaryAction the primary action on the resource.
     * @param id the id of the particular resource
     * @param request the request object
     * @return an updated request object sufficient to complete the request.
     */
    public abstract CsdwaRequest handlePostRequest(CsdwaRequest request);

    /**
     * This method provides an entry hook, for setup purposes before calling the
     * core handler.
     *
     * @param request the request object
     * @return the request object
     */
    protected CsdwaRequest requestStartHandle(CsdwaRequest request) {
        this.initialActionTypeId = InfoAggregator.getInstance().getActionTypeId(request.getPrimaryActionTypeName());
        this.initialResourceTypeId = InfoAggregator.getInstance().getResourceTypeId(request.getPrimaryResourceTypeName());
        return request;
    }

    /**
     * This method is the primary handler for the request
     *
     * @param request the request object
     * @return a handled request
     */
    protected CsdwaRequest requestCoreHandle(CsdwaRequest request) {
        if (request.getMethod().equals("POST")) {
            request = this.handlePostRequest(request);
        } else {
            request = this.handleGetRequest(request);
        }
        return request;
    }

    /**
     * This method handles the request last and is used for ensuring action's
     * shared by the resource types are always performed.
     *
     * @param request the request object
     * @return the completed request
     */
    protected CsdwaRequest requestEndHandle(CsdwaRequest request) {

        int eventCreatorId = request.getCurrentUser().getId();
        int actionId = this.initialActionTypeId;
        int subjectId = request.getPrimaryResourceId();
        int subjectStateId = 0;
        int subjectResourceTypeId = this.initialResourceTypeId;
        String subjectName = "Undefined";
        // determine task action id from the initial action and resource id.
        int taskActionId = InfoAggregator.getInstance().getTaskActionId(actionId, subjectResourceTypeId);

        // if this request contains a bean that is notifiyable, then update the resource information.
        if (request.getBean() != null && request.getBean() instanceof CsdwaNotifiable) {
            CsdwaNotifiable post = (CsdwaNotifiable) request.getBean();
            subjectId = post.getId();
            subjectName = post.getName();
            subjectResourceTypeId = post.getResourceTypeId();
            subjectStateId = post.getStateId();
        }

        this.ResourceRequestDelegator.getNotificationManager().listen(eventCreatorId, taskActionId, subjectId, subjectStateId, subjectResourceTypeId, subjectName);

        /**
         * Ajax code
         */
        if (request.getRequestType() == RequestType.ASYNC) {
            System.out.println("request type is ASYNC in ResourceController");
            request.setMessageType(request.getMessageType());
        }
        return request;
    }

    /**
     * @return the ResourceRequestDelegator
     */
    public ResourceRequestDelegator getResourceRequestDelegator() {
        return ResourceRequestDelegator;
    }

    /**
     * @param ResourceRequestDelegator the ResourceRequestDelegator to set
     */
    public void setResourceRequestDelegator(ResourceRequestDelegator rrd) {
        this.ResourceRequestDelegator = rrd;
    }
}
